/*
 * @Author: zhaoxiangyu@
 * @Date: 2021-11-05 10:38:41
 * @LastEditors: 647355931@qq.com
 * @LastEditTime: 2021-11-05 17:41:23
 * @Description: file content
 */

import observe from "./observe.js";

// 数组响应式 需要重写数组原型链上的方法 达到数组的修改与获取
const arrayProto = Array.prototype; //获取到数组原型链
const arrayMethods = Object.create(arrayProto); //copy一份
// 要重写的原型
const methodsToPatch = [
  "push",
  "pop",
  "unshift",
  "shift",
  "splice",
  "sort",
  "reverse",
];

methodsToPatch.forEach((methods) => {
  Object.defineProperty(arrayMethods, methods, {
    value: function (...args) {
      // console.log("..args==> ", ...args);
      // 将数组方法指向为当前数组  (不改变他的原有操作)
      // 先执行原来的操作  然后执行自己的操作
      const ret = arrayProto[methods].apply(this, args);
      const dep = this.__ob__;
      // console.log("拦截_____array");
      let inserted;
      // 如果有新增的元素  如果用户新增了数据  那么新增的同时 也为该数据 添加响应式
      switch (methods) {
        case "push":
        case "unshift":
          inserted = args;
          break;
        case "splice":
          inserted = args.slice(2);
          break;
      }
      // 如果inserted 有值 表示有新数据
      if (inserted) {
        // observe(inserted);
        // 对新增元素进行响应式更新
        // this  就是我们调用 this.xxx 时得值
        dep.observerArray(inserted);
      }

      // 通知更新
      dep.dep.notify();

      return ret;
    },
    configurable: true,
    writable: true,
    enumerable: false,
  });
});

export default function protoAgument(arr) {
  // console.log('arr===> ', arr)
  arr.__proto__ = arrayMethods;
}
